﻿
Imports std

Public Module shared_parameters_mappings
    Public ReadOnly mi As iParametersMapping = Nothing
    Public ReadOnly mio As iParametersMapping = Nothing
    Public ReadOnly mname As iParametersMapping = Nothing
    Public ReadOnly mname_ps As iParametersMapping = Nothing
    Public ReadOnly mi_ps As iParametersMapping = Nothing
    Public ReadOnly mkey As iParametersMapping = Nothing
    Public ReadOnly m_name_value As iParametersMapping = Nothing

    Sub New()
        initialMapping(mi, "i")
        initialMapping(mio, "i", "o")
        initialMapping(mname, "name")
        initialSerialMapping1(mname_ps, "name", "p")
        initialSerialMapping1(mi_ps, "i", "p")
        initialMapping(mkey, "key")
        initialMapping(m_name_value, "name", "value")
    End Sub
End Module

Public MustInherit Class templateFunction(Of OT)
    Inherits internalFunction

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping, _
                      ByVal ps As parameters_list, ByVal a As aliases)
        MyBase.New(name, m, ps, a)
    End Sub

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping, ByVal a As aliases)
        MyBase.New(name, m, a)
    End Sub

    Protected Sub New(ByVal name As String, ByVal aliases As aliases)
        MyBase.new(name, aliases)
    End Sub

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping)
        MyBase.New(name, m)
    End Sub

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected MustOverride Function returnType() As typeDefination

    Protected Overridable Function elementType1() As typeDefination
        Return typeDefination.unknown
    End Function

    Protected Overridable Function elementType2() As typeDefination
        Return typeDefination.unknown
    End Function

    Protected MustOverride Overloads Function invoke(ByVal ctx As context, ByRef o As OT) As Boolean

    Protected NotOverridable Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
        Dim o As OT = Nothing
        If Not invoke(ctx, o) Then
            raiseError("cannot invoke in " + Me.GetType().FullName(), errorHandle.errorType.warning)
            Return False
        End If

        output = New bare_variable(returnType(), elementType1(), elementType2(), o)
        Return True
    End Function
End Class

Public MustInherit Class template_finder_function(Of IT, OT)
    Inherits templateFunction(Of OT)

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping, _
                      ByVal ps As parameters_list, ByVal a As aliases)
        MyBase.New(name, m, ps, a)
    End Sub

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping, ByVal a As aliases)
        MyBase.New(name, m, a)
    End Sub

    Protected Sub New(ByVal name As String, ByVal aliases As aliases)
        MyBase.new(name, aliases)
    End Sub

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping)
        MyBase.New(name, m)
    End Sub

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected MustOverride Function finder() As iVariableFinder(Of IT)
End Class

Public MustInherit Class noInputFunction(Of OT)
    Inherits templateFunction(Of OT)

    Protected Sub New(ByVal name As String, ByVal a As aliases)
        MyBase.New(name, a)
    End Sub

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected MustOverride Overloads Function invoke(ByRef o As OT) As Boolean

    Protected NotOverridable Overrides Function invoke(ByVal ctx As context, ByRef o As OT) As Boolean
        Return invoke(o)
    End Function
End Class

Public MustInherit Class inputIFunction(Of IT, OT)
    Inherits template_finder_function(Of IT, OT)

    Public Class parameters
        Public Const i As String = "i"
    End Class

    Private _noInput As Boolean = False

    Protected Sub New(ByVal name As String, ByVal a As aliases)
        MyBase.New(name, shared_parameters_mappings.mi, a)
    End Sub

    Protected Sub New(ByVal name As String)
        Me.New(name, Nothing)
    End Sub

    Protected MustOverride Overloads Function invoke(ByVal i As IT, ByRef o As OT) As Boolean

    Protected Function noInput() As Boolean
        Return _noInput
    End Function

    Protected Overridable Function enableNoInput() As Boolean
        Return False
    End Function

    Protected NotOverridable Overrides Function invoke(ByVal ctx As context, ByRef o As OT) As Boolean
        Dim i As IT = Nothing
        If Not finder().find(ctx, parameters.i, i) Then
            If Not enableNoInput() Then
                raiseError("expect parameter " + parameters.i, errorHandle.errorType.user)
                Return False
            Else
                _noInput = True
                i = Nothing
            End If
        Else
            _noInput = False
        End If

        Return invoke(i, o)
    End Function
End Class

Public MustInherit Class inputIOutputOFunction(Of IT, OT)
    Inherits template_finder_function(Of IT, Boolean)

    Public Class parameters
        Public Const i As String = "i"
        Public Const o As String = "o"
    End Class

    Protected Sub New(ByVal name As String, ByVal a As aliases)
        MyBase.New(name, shared_parameters_mappings.mio, a)
    End Sub

    Protected Sub New(ByVal name As String)
        Me.New(name, Nothing)
    End Sub

    Protected NotOverridable Overrides Function returnType() As typeDefination
        Return typeDefination.bool
    End Function

    Protected Overridable Function enableNoInput() As Boolean
        Return False
    End Function

    Protected Overridable Function outputType() As typeDefination
        Return typeDefination.var
    End Function

    Protected MustOverride Overloads Function invoke(ByVal i As IT, ByRef o As OT) As Boolean

    Protected NotOverridable Overrides Function invoke(ByVal ctx As context, ByRef rst As Boolean) As Boolean
        Dim i As IT = Nothing
        If Not finder().find(ctx, parameters.i, i) Then
            If Not enableNoInput() Then
                raiseError("expect parameter " + parameters.i, errorHandle.errorType.user)
                Return False
            Else
                i = Nothing
            End If
        End If
        Dim ob As bare_variable = Nothing
        If Not bare_variable_finder().find(ctx, parameters.o, ob) OrElse _
           Not ob.variable().isPointerOf(outputType()) Then
            raiseError("expect parameter " + parameters.o + " is pointer<" + typeNaming(outputType()) + ">.", _
                       errorHandle.errorType.user)
            Return False
        End If

        Dim o As OT = Nothing
        rst = invoke(i, o)
        If rst Then
            If ob.variable().elementType1() = typeDefination.var Then
                convertor.cast(Of pointer(Of pointer(Of Object)))(ob.value()).instance().setinstance(o)
            Else
                convertor.cast(Of pointer(Of pointer(Of OT)))(ob.value()).instance().setinstance(o)
            End If
        End If
        Return True
    End Function
End Class

Public MustInherit Class _x_ps_function(Of xT, pT, oT)
    Inherits templateFunction(Of oT)

    Public Class parameters
        Public Const i As String = "i"
        Public Const pbase As String = "p"
    End Class

    Protected Sub New(ByVal name As String, ByVal m As iParametersMapping)
        MyBase.New(name, m)
    End Sub

    Protected Sub New(ByVal name As String)
        Me.New(name, shared_parameters_mappings.mi_ps)
    End Sub

    Protected MustOverride Function x_finder() As iVariableFinder(Of xT)
    Protected MustOverride Overloads Function invoke(ByVal ctx As context, ByVal x As xT, _
                                                     ByVal ps As pT, ByRef o As oT) As Boolean
    Protected MustOverride Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                                    ByRef obj As Object) As Boolean

    Protected Overridable Function x_name() As String
        Return parameters.i
    End Function

    Protected NotOverridable Overrides Function invoke(ByVal ctx As context, ByRef o As oT) As Boolean
        Dim x As xT = Nothing
        If x_finder().find(ctx, x_name(), x) Then
            Dim ps As pT = Nothing
            ctx.findVariables(AddressOf findvariablesCB, bare_variable_finder(), parameters.pbase, obj:=ps)
            Return invoke(ctx, x, ps, o)
        Else
            raiseError("expect parameter " + x_name(), errorHandle.errorType.user)
            Return False
        End If
    End Function
End Class

Public MustInherit Class _name_ps_function(Of PT, OT)
    Inherits _x_ps_function(Of String, PT, OT)

    Public Shadows Class parameters
        Public Const name As String = "name"
    End Class

    Protected Sub New(ByVal name As String)
        MyBase.New(name, shared_parameters_mappings.mname_ps)
    End Sub

    Protected NotOverridable Overrides Function x_name() As String
        Return parameters.name
    End Function

    Protected NotOverridable Overrides Function x_finder() As iVariableFinder(Of String)
        Return string_finder()
    End Function
End Class

Public Class _object_ps
    Private Shared Function insertParameters(ByVal var As bare_variable, ByVal o As vector(Of Object)) As Boolean
        If var Is Nothing Then
            o.push_back(CType(Nothing, Object))
        Else
            o.push_back(var.value())
        End If

        Return True
    End Function

    Public Shared Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                           ByRef obj As Object) As Boolean
        If obj Is Nothing Then
            obj = New vector(Of Object)()
        End If

        Return insertParameters(var, convertor.cast(Of vector(Of Object))(obj))
    End Function
End Class

Public Class _parameters_t_ps
    Private Shared Function insertParameter(ByVal name As String, ByVal var As bare_variable, _
                                            ByVal ps As parameters_t) As Boolean
        ps.push_back(make_pair(name, var))
        Return True
    End Function

    Public Shared Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                           ByRef obj As Object) As Boolean
        If obj Is Nothing Then
            obj = New parameters_t()
        End If

        Return insertParameter(name, var, convertor.cast(Of parameters_t)(obj))
    End Function
End Class

'parameters, name, the function name
'            p0 ... pn, the input parameters to the function
'return, var, the return from function
Public MustInherit Class name_object_ps_function(Of OT)
    Inherits _name_ps_function(Of vector(Of Object), OT)

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected NotOverridable Overrides Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                                                ByRef obj As Object) As Boolean
        Return _object_ps.findvariablesCB(name, var, obj)
    End Function
End Class

Public MustInherit Class name_parameters_t_ps_function(Of OT)
    Inherits _name_ps_function(Of parameters_t, OT)

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected NotOverridable Overrides Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                                                ByRef obj As Object) As Boolean
        Return _parameters_t_ps.findvariablesCB(name, var, obj)
    End Function
End Class

Public MustInherit Class x_object_ps_function(Of xT, oT)
    Inherits _x_ps_function(Of xT, vector(Of Object), oT)

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected NotOverridable Overrides Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                                                ByRef obj As Object) As Boolean
        Return _object_ps.findvariablesCB(name, var, obj)
    End Function
End Class

Public MustInherit Class x_parameters_t_ps_function(Of xT, oT)
    Inherits _x_ps_function(Of xT, parameters_t, oT)

    Protected Sub New(ByVal name As String)
        MyBase.New(name)
    End Sub

    Protected NotOverridable Overrides Function findvariablesCB(ByVal name As String, ByVal var As bare_variable, _
                                                                ByRef obj As Object) As Boolean
        Return _parameters_t_ps.findvariablesCB(name, var, obj)
    End Function
End Class
